/**
 * 
 */
package edu.vanderbilt.vshare.multicast;

/**
 * class for working with weighted work units
 * @author jedmondson
 *
 */
public class WeightedWorkUnit extends WorkUnit {

	/**
	 * Copy constructor for a WorkUnit. Weight is set to 1.
	 * 
	 * @param     unit               unit to copy from
	 */
	
	WeightedWorkUnit (WorkUnit unit)
	{
		super (unit);
		weight = 1;
	}

	/**
	 * Packet constructor. Weight is set to 1
	 * 
	 * @param     packet             packet index for this work
	 */
	
	WeightedWorkUnit (int packet)
	{
		super (packet);
		weight = 1;
	}

	/**
	 * Copy constructor for a WeightedWorkUnit.
	 * 
	 * @param     unit               unit to copy from
	 */
	
	WeightedWorkUnit (WeightedWorkUnit unit)
	{
		super (unit.address, unit.fileid, unit.packet);
		weight = 1;
	}

	/**
	 * Copy constructor for a WorkUnit with a user defined weight
	 * 
	 * @param     unit               unit to copy from
	 * @param     weight             weight to assign to this Work Unit
	 */
	
	WeightedWorkUnit (WorkUnit unit, int weight)
	{
		super (unit);
		this.weight = weight;
	}

	/**
	 * Constructor for a WeightedWorkUnit built from WorkUnit parts. Weight
	 * is set to 1.
	 * 
	 * @param     address            multicast ip address
	 * @param     fileid             id of file
	 * @param     packet             packet to send
	 */
	
	WeightedWorkUnit (byte [] address, int fileid, int packet)
	{
		super (address, fileid, packet);
		weight = 1;
	}

	/**
	 * Constructor for a WeightedWorkUnit built from WorkUnit parts.
	 * 
	 * @param     address            multicast ip address
	 * @param     fileid             id of file
	 * @param     packet             packet to send
	 * @param     weight             user defined weight for this unit
	 */
	
	WeightedWorkUnit (byte [] address, int fileid, int packet, 
			int weight)
	{
		super (address, fileid, packet);
		this.weight = weight;
	}

	/**
	 * return the weight of this work unit
	 * 
	 * @return                       weight for this work unit
	 */
	
	public synchronized int getWeight()
	{
		return weight;
	}

	/**
	 * increment and return the new weight atomically
	 * 
	 * @return                       weight for this work unit
	 */
	
	public synchronized int incWeight()
	{
		return ++weight;
	}

	/**
	 * atomically reset weight to zero and returns new value (zero)
	 * 
	 * @return                       weight for this work unit
	 */
	
	public synchronized int resetWeight()
	{
		return weight = 0;
	}

	/**
	 * atomically set weight to a user specified value
	 * 
	 * @param     weight             user defined weight for this unit
	 * @return                       new weight
	 */
	
	public synchronized int setWeight(int weight)
	{
		return this.weight = weight;
	}
	
	private int weight;
}
